import kotlin.time.ExperimentalTime

@OptIn(ExperimentalTime::class)
fun main() {

//    val intArray = intArrayOf(
//        1,
//        2,
//        3,
//        4,
//        5,
//        6,
//        7,
//        8,
//        9,
//        10,
//        11,
//        12,
//        13,
//        14,
//        15,
//        16,
//        17,
//        18,
//        19,
//        20,
//        21,
//        22,
//        23,
//        24,
//        25,
//        26,
//        27,
//        28,
//        29,
//        30,
//        31,
//        32,
//        33,
//        34,
//        35,
//        36,
//        37,
//        38,
//        39,
//        40,
//        41,
//        42,
//        43,
//        44,
//        45,
//        46,
//        47,
//        48,
//        49,
//        50,
//        51,
//        52,
//        53,
//        54
//    )
//        val intArray = intArrayOf(1, 2, 3, 4, 5, 6, 7)
//    val intArray = intArrayOf(1, 2, 3, 4, 5, 6)
    val intArray = intArrayOf(2, 3, 7, 8, 2, 4)//242378
//    val intArray = intArrayOf(1)
//    val intArray = intArrayOf(-1, -100, 3, 99)
    val k = 4
//    val k = 45
    val test = 轮转数组2()
//    test.test2(intArray, k)
    test.answer(intArray, k)
    println(intArray.contentToString())
}

class 轮转数组2 {

    /**
     * 翻转法
     * */
    fun answer(nums: IntArray, k: Int) {
        val size = nums.size
        if (size <= 1 || k == 0 || size == k) return
        val p = k % size
        reverse(nums, 0, size)
        reverse(nums, 0, p)
        reverse(nums, p, size)
    }

    /**
     * 将 nums数组在start和end之间的元素反转（左闭右开）
     *
     * @param nums
     * @param start
     * @param end
     */
    private fun reverse(nums: IntArray, start: Int, end: Int) {
        val len = (end - start) / 2
        var tem: Int
        for (i in 0 until len) {
            tem = nums[start + i]
            nums[start + i] = nums[end - 1 - i]
            nums[end - 1 - i] = tem
        }
    }

    fun test2(nums: IntArray, k: Int) {//重点是判断相同时是替换还是跳过
        val size = nums.size
        if (size <= 1 || k == 0 || size == k) return
        var mark = nums[0]
        var markP = 0
        var p = 0
        var count = 0
        while (count != size) {
            val p2 = (p + k) % size
            if (p2 == markP) {
                nums[p2] = mark
                p = (p2 + 1) % size
                mark = nums[p]
                markP = p
            } else {
                val i2 = nums[p2]
                nums[p2] = mark
                mark = i2
                p = p2
            }
            count++
        }
    }

    fun test(nums: IntArray, k: Int) {//重点是判断相同时是替换还是跳过
        val size = nums.size
        if (size <= 1 || k == 0 || size == k) return
        var mark = nums[0]
        var markP = 0
        var p = 0
        var count = 0
        while (count != size) {
            val p2 = (p + k) % size
            if (mark == nums[p2]) {
                if (p == markP) {
                    mark = nums[(p + 1) % size]//跳过
                    p++
                    markP = p
                    continue
                } else {
                    mark = nums[p2]
                    p = p2
                }
            } else {
                val i2 = nums[p2]
                nums[p2] = mark
                mark = i2
                p = p2
            }
//        println("$i:" + nums.contentToString() + ",mark:$mark,i2:$i2,p2:$p2")
            count++
        }
    }
}

